
package fileby.plugins.exported;

import fileby.plugins.IPluggable;
import fileby.plugins.IPluginAnnotation;
import fileby.plugins.IToolbox;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import javax.swing.JOptionPane;

/**
 *
 * @author Oscar
 */
@IPluginAnnotation(name = "Merge folders", description = "merge your folders into one new folder.")
public class MergeFolderPlugin implements IPluggable {
    private  Map<Long, File> checksums = new HashMap();
    private  List<File> sameChecksum = new ArrayList<File>();
    private  boolean success = true;

    public boolean run(IToolbox toolbox) {
        List<File> files = toolbox.getFiles();
        List<File> mergedFiles = new ArrayList<File>();
        String folderName = "";
        
        if (files != null) {
            //get the files that will be merged
            for (File f : files) {
                if (f.isDirectory()) {
                    for (File fi : f.listFiles()) {
                        if(fi.isFile() && isNewChecksum(fi))
                            mergedFiles.add(fi);
                        else if(fi.isDirectory())
                            mergedFiles.add(fi);
                    }
                } else if (f.isFile()) {
                    if(isNewChecksum(f))
                        mergedFiles.add(f);
                }
            }

            //Check if the name for the new folder doesn´t alredy excist.
            folderName = JOptionPane.showInputDialog(null, "Name for the new merged directory: ", "MergedFolder");
            boolean nameAlredyExcist = true;
            while (nameAlredyExcist) {
                for (File f : Arrays.asList(toolbox.getDirectory().listFiles())) {
                    if (f.getName().equals(folderName)) {
                        nameAlredyExcist = true;
                        folderName = JOptionPane.showInputDialog("The name alredy excist, please choose another name: ", "MergedFolder");
                        break;
                    } else {
                        nameAlredyExcist = false;
                    }
                }
            }

            if (folderName != null) {
                File directory = new File(toolbox.getDirectory().getAbsolutePath() + "/" + folderName);

                //Move the files to the new folder
                if (directory.mkdir()) {
                    for (File f : mergedFiles) {
                        if (!f.renameTo(new File(directory.getAbsoluteFile(), f.getName()))) {
                            System.out.println(" ");
                        }
                    }
                }

              //delete the files/folders with same checksum as alredy moved files.
                for (File f : sameChecksum){
                    if(!f.delete())
                        System.out.println(f.getName()+ " could not be deleted");
                }
          

                //delete the old folders if all files are gone
                for (File f : files) {
                    if (f.isDirectory() && Arrays.asList(f.list()).isEmpty()) {
                        if(!f.delete())
                            System.out.println(f.getName() + " could not be deleted");
                    } else if (f.isFile() && !mergedFiles.contains(f)) {
                        if(!f.delete())
                           System.out.println(f.getName() + " could not be deleted");
                    }
                }

                toolbox.clearMagicBox();

                for (File f : directory.listFiles()) {
                    if(mergedFiles.contains(f))
                        success = false;
                        break;
                }
                if (!success) {
                    JOptionPane.showMessageDialog(null, "All files could bot be moved");
                }
            }
        }
        checksums.clear();
        mergedFiles.clear();
        return success;
    }

     private boolean isNewChecksum(File f) {
        boolean isNewChecksum = false;
        CheckedInputStream in = null;
        byte[] bytes = new byte[1024];
        try {
            in = new CheckedInputStream(new FileInputStream(f), new CRC32());
            while (in.read(bytes) > -1) {}
            if (checksums.containsKey(in.getChecksum().getValue())){
                isNewChecksum = false;
                sameChecksum.add(f);
            }
            else {
                isNewChecksum = true;
                checksums.put(in.getChecksum().getValue(), f);
            }

        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        finally {
            try {
                in.close();
            } catch (IOException ex) {
                success = false;
                ex.printStackTrace();
            }
            return isNewChecksum;
        }
    }
}
